package cn.wp.ewallet.upms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.wp.common.core.WpVar;
import cn.wp.common.core.exception.WpDaoException;
import cn.wp.common.core.id.Id;
import cn.wp.common.core.model.WpPage;
import cn.wp.common.core.model.WpState;
import cn.wp.common.core.util.BeanUtil;
import cn.wp.ewallet.upms.dao.DemoDao;
import cn.wp.ewallet.upms.model.dto.DemoDto;
import cn.wp.ewallet.upms.model.entity.DemoDo;
import cn.wp.ewallet.upms.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;

/**
 * 样例
 * Created by chenyb on 2019/09/29
 */
@Service
public class DemoServiceImpl implements DemoService {

    @Autowired
    private DemoDao demoDao;

    @Autowired
    private TransactionTemplate transactionTemplate;

    private int id;

    @Override
    public WpState saveDemo(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        // 生成主键ID
        demoDo.setId(Id.gen());
        demoDo.setCreateDatetime(DateUtil.date());
        int state = demoDao.insertDemo(demoDo);
        return new WpState(state);
    }

    /**
     * 多表增删改操作，添加@Transactional启用事务
     * @param demoDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public WpState saveDemo2(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        // 生成主键ID
        demoDo.setId(Id.gen());
        demoDo.setCreateDatetime(DateUtil.date());
        int state = demoDao.insertDemo(demoDo);
        return new WpState(state);
    }

    /**
     * 事务模板使用，与 @Transactional不可同时存在
     * 达到细粒度控制数据库锁的持有时间
     * @param demoDto
     * @return
     */
    public WpState saveDemo3(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    //doSomthing;
                    demoDao.insertDemo(demoDo);
                    demoDao.deleteDemo(demoDo);
                } catch (Exception e) {
                    // 事务回滚
                    status.setRollbackOnly();
                    throw new WpDaoException("数据访问层出错",e);
                }
            }
        });

        //其他耗时操作

        // 发送邮件
        // email.send();

        // 上传文件
        // file.upload();


        return new WpState(WpVar.YES_FOR_INT);
    }

    @Override
    public WpState modifyDemo(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        int state = demoDao.updateDemo(demoDo);
        return new WpState(state);
    }

    @Override
    public WpState removeDemoById(String id) {
        int state = demoDao.deleteDemoById(id);
        return new WpState(state);
    }

    @Override
    public WpState removeDemo(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        int state = demoDao.deleteDemo(demoDo);
        return new WpState(state);
    }

    private DemoDo demoDo = null;
    @Override
    public synchronized List<DemoDto> getDemoList(DemoDto demoDto) {
        id++;
        System.err.println(Thread.currentThread().getName() + ":id:" + id);
        /*DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        List<DemoDo> list = demoDao.selectDemoList(demoDo);
        return BeanUtil.listCopyProperties(list, DemoDto.class, new BeanUtil.Processor<DemoDo,DemoDto>() {
            @Override
            public void convert(DemoDo source, DemoDto target) {
                target.setCreateDatetime(DateUtil.formatDateTime(source.getCreateDatetime()));
            }
        });*/
        return null;
    }

    @Override
    public WpPage<DemoDto> getDemoList(DemoDto demoDto, WpPage wpPage) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        demoDao.selectDemoList(demoDo,wpPage);
        return wpPage.doConvertDto(DemoDto.class);
    }

    @Override
    public int countDemo(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        return demoDao.countDemo(demoDo);
    }

    @Override
    public DemoDto getDemoById(String id) {
        DemoDo demoDo = demoDao.selectDemoById(id);
        return BeanUtil.copyProperties(demoDo,DemoDto.class);
    }

    @Override
    public int modifyType(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        return demoDao.updateType(demoDo);
    }

    @Override
    public DemoDto getDemoByCache(DemoDto demoDto) {
        DemoDo demoDo = BeanUtil.copyProperties(demoDto,DemoDo.class);
        demoDo = demoDao.selectDemoByCache(demoDo);
        return BeanUtil.copyProperties(demoDo,DemoDto.class);
    }

}